#pragma once 

#include "Connection.h"
#include "InetAddress.h"
#include "MsgBuffer.h"
#include <functional> 
#include <memory>
#include <list>
#include<vector>
#include<sys/uio.h>

namespace tmms
{
    namespace network
    {
        class TcpConnection;
        using TcpConnectionPtr = std::shared_ptr<TcpConnection>;
        using CloseConnectionCallback = std::function<void(const TcpConnectionPtr &)>;
        using MessageCallback = std::function<void(const TcpConnectionPtr &,MsgBuffer &buffer)>;
        using WriteCompleteCallback = std::function<void(const TcpConnectionPtr &)>;
        using TimeoutCallback = std::function<void(const TcpConnectionPtr &)>;
        


    
        struct TimeoutEntry;//前置声明

        class TcpConnection:public Connection
        {
        public:
            TcpConnection(EventLoop *loop,
                         int socketfd,
                         const InetAddress &localAddr,
                         const InetAddress& peerAddr);

            virtual ~TcpConnection();

            void setCloseCallback(const CloseConnectionCallback &cb);
            void setCloseCallback( CloseConnectionCallback &&cb);

            void setRecvMsgCallback(const MessageCallback &cb);
            void setRecvMsgCallback(MessageCallback &&cb);

            void OnClose() override;
            void ForceClose() override;
                
            void OnRead() override;
            void OnError(const std::string &msg) override;

            //写事件成员变量
            void OnWrite() override;
            void SetWriteCompleteCallback(const WriteCompleteCallback &cb); 
            void SetWriteCompleteCallback(const WriteCompleteCallback &&cb);
            void Send(std::list<BufferNodePtr> &list);
            void Send(const char *buf,size_t size);

            //超时事件相关的
            void SetTimeoutCallback(int timeout,const TimeoutCallback &cb);
            void SetTimeoutCallback(int timeout,TimeoutCallback &&cb);
            void OnTimeout();
            void EnableCheckIdleTimeout(int32_t max_time);

        private:

            bool closed_{false};
            CloseConnectionCallback close_cb_;
            MsgBuffer  message_buffer_;
            MessageCallback  message_cb_;

            //与写事件有关的
            void SendInLoop(const char *buf,size_t size);
            void SendInLoop(std::list<BufferNodePtr> &list);

            //向量，一个个待写入的数据
            std::vector<struct iovec> io_vec_list_;
            WriteCompleteCallback write_complete_cb_;
               
            //与超时事件有关的
            std::weak_ptr<TimeoutEntry> timeout_entry_;//TODO:这里为何一定要是弱引用
            int32_t max_idle_time_{30};
            void ExtendLife();//延长声明周期的
        };


        struct TimeoutEntry
        {
            public:
            TimeoutEntry(const TcpConnectionPtr &connection) :conn(connection){};
            std::weak_ptr<TcpConnection> conn;

            ~TimeoutEntry(){
                auto c =conn.lock();//尝试从weak_ptr获取一个有效的shared_ptr
                if(c)
                {
                    c->OnTimeout();  //用它的时候，这个class TcpConnection 必须先定义才可以使用
                }
            };

        };
    }
} 
